class Cart {
  constructor() {
    this.axiosRes();
    this.checkLogin();
    this.getData();
    this.bindEve();
  }

  /******axios的响应拦截********/
    axiosRes() {
    // 添加响应拦截器
    axios.interceptors.response.use(
      function (response) {
        // 对响应数据做点什么
        // console.log(response);
        // 判断接口状态
        if (response.data.code == 401) {
          location.assign("./login.html?returnUrl=./cart.html");
        }
        return response;
      },
      function (error) {
        // 对响应错误做点什么
        return Promise.reject(error);
      }
    );
  }

  /*******绑定事件的方法*******/
  bindEve() {

    // 全选按钮绑定点击事件
    this.$(".cart-th input").addEventListener("click",this.allCheck.bind(this));

    // 给商品共同父级绑定事件,实现委托
    this.$(".cart-list").addEventListener("click", this.dispatch.bind(this));

    // 给input绑定输入事件
    this.$(".cart-list").addEventListener("input", this.changeNum.bind(this));
  }

  /*******区分当前的操作*****/
  dispatch(eve) {
    // 获取当前事件源
    let tar = eve.target;

    // 判断当前事件源是否含有类名goods-checkbox
    if (tar.classList.contains("goods-checkbox")) {
      // 调用单个按钮状态的函数
      this.manageOG(tar);
      //统计数量和价格
      this.totalSP();
    }

    // 判断点击的是否为删除
    if (tar.classList.contains("del-goods")) {
      this.delGoods(tar);
    }

    // 判断点击是否+ -
    if (tar.classList.contains("plus") || tar.classList.contains("mins")) {
      //   console.log(33333);
      this.changeNum(eve);
    }
  }

  /*******修改数量的方法*******/
  changeNum(eve) {
    // 判断当前操作的是否为输入框
    if (eve.target.type == "checkbox") return;
    // console.log(eve);

    // 根据事件类型区分当前是输入和点击操作
    // console.log(eve.target);
    // console.log(eve.type);
    let input = "";
    let val = 0;
    if (eve.type == "click") {
      // 判断当前点击的为+,还是-
      let mark = eve.target.innerHTML;
      if (mark == "+") {
        input = eve.target.previousElementSibling;
        val = input.value - 0 + 1;

        let ulObj = document.querySelectorAll('.goods-list');
        // console.log(ulObj);
        this.changeCartNum(ulObj);
      }

      if (mark == "-") {
        // 获取input框
        input = eve.target.nextElementSibling;
        // 修改数量
        val = input.value - 1;
        // 数量小于1,则设置为1
        if (val < 1) val = 1;

        let ulObj = document.querySelectorAll('.goods-list');
        this.changeCartNum(ulObj);
      }

      // console.log(input);
      input.value = val;
    }

    if (eve.type == "input") {
    }
    this.sumPrice(val, eve.target);
  }

  /*****小计的实现*******/
  sumPrice(num, target) {
    // console.log(11111);

    // 找到最大父级ul
    let ul = this.deep(target);
    // console.log(ul, num);

    // 获取单价
    let price = this.getChildren(ul, ".price", "innerHTML");
    // console.log(price);
    let sum = ul.querySelector(".sum");
    // console.log(sum);

    // 保留两位小数
    sum.innerHTML = (num * price).toFixed(2);

    // 发送ajax,修改服务器商品数量
    let goodsId = ul.dataset.id;
    this.sendAjaxNum(goodsId, num);

    // 计算总价
    this.totalSP();
  }

  // 防抖的使用    lock = false;
  times = "";
  /********修改服务器数量*****/
  sendAjaxNum(goodsId, num) {
    // 使用防抖减少发送次数
    // if (this.lock) return;
    // this.lock = true;
    // setTimeout(() => {
    //   this.lock = false;
    // }, 300)
    clearTimeout(this.times);
    this.times = setTimeout(() => {
      axios.defaults.headers["Content-Type"] =
        "application/x-www-form-urlencoded";

      axios.defaults.headers.common["Authorization"] =
        localStorage.getItem("token");

      let userId = localStorage.getItem("use_id");
      // 对参数编码
      let param = `goodsId=${goodsId}&number=${num}&id=${userId}`;
      axios.post("http://localhost:8888/cart/number", param).then((res) => {
        // console.log(res);
      });
    }, 300);
  }

  /*******删除的实现*****/
  delGoods(tar) {
    let redayDel = this.deep(tar);
    // console.log(redayDel);
    let that = this;
    layer.msg("确定残忍的抛弃奴家吗?", {
      time: 20000, //20s后自动关闭
      btn: ["确定", "取消"],
      yes(index) {
        layer.close(index);
        // console.log(1111);
        // 获取商品id和用户id,删除ul
        let userId = localStorage.getItem("use_id");
        let token = localStorage.getItem("token");

        let goodsId = redayDel.dataset.id;
        axios.defaults.headers.common["Authorization"] = token;

        // 发送ajax请求
        axios.get("http://localhost:8888/cart/remove?id=" +userId +"&goodsId=" +goodsId)
          .then(({ status, data }) => {
            // console.log(res);

            // 判断服务器状态和接口状态
            if (status == 200 && data.code == 1) {
              // console.log(this);
              // 获取当前商品是否选中,决定是否调用价格同价的方法
              // console.log(that.getChildren(redayDel, '.goods-checkbox', 'checked'));
              // 删除ul标签
              redayDel.remove();

              
              // console.log(status, data);
              that.getChildren(redayDel, ".goods-checkbox", "checked") && that.totalSP();

              let ulObj = document.querySelectorAll('.goods-list');
              console.log(ulObj);
              this.changeCartNum(ulObj);
            }
          });
      },
    });
  }

  /********递归找到父级ul*****/
  deep(ele, tar = "ul") {
    if (ele.nodeName == tar.toUpperCase()) {
      // 结果返回到   return this.deep(ele.parentNode) (内部调用)
      return ele;
    }
    // return 结束代码执行,虽然下方代码被调用多次,但是return没有返回,因为后面有函数
    // 当函数执行完成,return只返回一次,就结束代码执行
    return this.deep(ele.parentNode);
  }

  /********验证是否登录**********/
  checkLogin() {
    const TOKEN = localStorage.getItem("token");
    if (!TOKEN) location.assign("./login.html?returnUrl=./cart.html");
  }

  /*******获取数据*******/
  async getData() {
    //获取用户id
    let userId = localStorage.getItem("use_id");
    // console.log(userId);

    //携带token
    axios.defaults.headers.common["Authorization"] = localStorage.getItem("token");

    // 发送ajax请求
    let { status, data } = await axios.get("http://localhost:8888/cart/list?id=" + userId);
    console.log(data,status);
    // 判断服务器状态
    if (status != 200) return;

    // 判断token是否过期
    if (data.code == 0) {
      location.assign("./login.html?returnUrl=./cart.html");
    }

    if (data.code == 1) {
      // 渲染购物车列表数据
      let html = "";
      data.cart.forEach((ele) => {
        // console.log(ele);
        html += `<ul class="goods-list yui3-g" data-id=${ele.goods_id}>
            <li class="yui3-u-3-8">
                <input type="checkbox" class="goods-checkbox">
                <div class="good-item">
                    
                    <div class="item-img">
                        <a href="./item.html?goods_id=${ele.goods_id}" ><img src="${ele.img_small_logo}"></a>
                    </div>
                    <div class="item-msg">${ele.title}</div>
                </div>
            </li>
            <li class="yui3-u-1-8"></li>
            
            <li class="yui3-u-1-8">
                <span class="price">${ele.current_price}</span>
            </li>
            <li class="yui3-u-1-8">
                <div class="clearfix">
                    <a href="#" class="increment mins">-</a>
                    <input autocomplete="off" type="text" value="${
                      ele.cart_number
                    }" minnum="1" class="itxt">
                    <a href="#" class="increment plus">+</a>
                </div>
                <div class="youhuo">有货</div>
            </li>
            <li class="yui3-u-1-8">
                <span class="sum">${ele.current_price * ele.cart_number}</span>
            </li>
            <li class="yui3-u-1-8">
                <div>
                    <a href="#none" class="del-goods">删除</a>
                </div>
                <div>移到我的关注</div>
            </li>
        </ul>`;
      });

      // 追加到页面中
      this.$(".cart-list").innerHTML = html;
      let ulObj = document.querySelectorAll('.goods-list');
      console.log(ulObj);
      this.changeCartNum(ulObj);
    }
  }
 /*********实时改变购物车的数量**********/
    changeCartNum(ulObj){
        let num = 0;
        setTimeout(() => {
          // let ulObj = document.querySelectorAll('.goods-list');
          //console.log(ulObj);
        ulObj.forEach(ele => {
            //console.log('el',ele);
            let value = this.getChildren(ele, '.itxt', 'value') - 0;
            console.log(value);
            num +=value;
        })
        this.$('.allgoods .num').innerHTML = num;
        this.$('.sui-btn .shopnum').innerHTML = num;
        }, 200);

    }
  /*********全选的实现********/
  allCheck(eve) {
    // console.log(eve.target);
    // 获取全选的状态
    let status = eve.target.checked;
    // console.log(status);
    this.setOneCheck(status);
    // 统计数量价格
    this.totalSP();
  }

  // 设置单个商品的状态
  setOneCheck(status) {
    let oneGoods = document.querySelectorAll(".goods-checkbox");
    // console.log(oneGoods);
    // 单个商品的状态跟随全选状态
    oneGoods.forEach((ele) => {
      ele.checked = status;
    });
  }

  /******单个商品点击状态******/
  manageOG(tar) {
    // console.log(tar, tar.checked);
    // 任何一个商品取消,全选取消
    if (tar.checked) {
      // 页面中有一个未被选中,全选不能选中
      let oneGoods = document.querySelectorAll(".goods-checkbox");
      // 都被选中res为false
      // 将伪数组转化为真数组
      // let res = [...oneGoods].some(ele => {
      //   return !ele.checked
      // });
      // // 设置全选选中
      // if (!res) this.$('.cart-th input').checked = true;

      ![...oneGoods].some((ele) => !ele.checked) &&
        (this.$(".cart-th input").checked = true);
    } else {
      this.$(".cart-th input").checked = false;
    }
  }

  /*******统计数量和价格********/
  totalSP() {
    // console.log(11111);

    // 数量和小计的累加
    let tNum = 0;
    let tPrice = 0;
    // 只统计选中的数量和价格
    let goodsList = document.querySelectorAll(".goods-list");
    // console.log(goodsList);
    goodsList.forEach((ul) => {
      let checkbox = this.getChildren(ul, ".goods-checkbox", "checked");
      if (checkbox) {
        let num = this.getChildren(ul, ".itxt", "value") - 0;
        let sum = this.getChildren(ul, ".sum", "innerHTML") - 0;
        // console.log(checkbox, num, sum);
        tNum += num;
        tPrice += sum;
      }
    });
    // console.log(tNum, tPrice);
    // 设置到页面中
    this.$(".sumprice-top strong").innerHTML = tNum;
    this.$(".sumprice-top .summoney").innerHTML = tPrice.toFixed(2);
  }

  // 获取父节点下的某个子节点
  getChildren(father, children, attr = "value") {
    // console.log('get',father.querySelector(children)[attr]);
    return father.querySelector(children)[attr];
  }

  // 获取节点的方法
  $(ele) {
    let res = document.querySelectorAll(ele);
    return res.length == 1 ? res[0] : res;
  }
}
new Cart();
